package com.anglireports.report.data.classPage;

import com.alibaba.fastjson.JSONObject;
import com.anglireports.report.bean.primary.Course;
import com.anglireports.report.bean.primary.Student;
import com.anglireports.report.bean.primary.Teacher;
import com.anglireports.report.bean.report.Concentration;
import com.anglireports.report.bean.report.Emotion;
import com.anglireports.report.bean.report.Reports;
import com.anglireports.report.bean.report.Vitality;
import com.anglireports.report.data.base.ResponseDataModel;
import com.anglireports.report.data.base.ResultCodeEnum;
import com.anglireports.report.data.chartCommon.*;
import com.anglireports.report.data.common.angli.AngliCommonData;
import com.anglireports.report.data.common.zhujian.CommonData;
import com.anglireports.report.response.anliResult.StudentModel;
import com.anglireports.report.response.result.ReportsResult;
import com.anglireports.report.response.util.CommonUtils;
import com.anglireports.report.response.util.DateUtil;

import java.util.*;

/**
 * 班级报表数据
 * @author lvjilei
 * @ceateTime 2019/3/28.
 */
public class ClassDataUtil {
    public static ResponseDataModel<ClassPageResponse> reponseData(String starttime, String endtime,
                                                            String courseid, String campusid){
        ResponseDataModel<ClassPageResponse> responseDataModel = new ResponseDataModel<>();
        if(null == starttime || endtime == null ||
                courseid== null){
            responseDataModel.setErr_code(ResultCodeEnum.PARAM_ERROR.getErr_code());
            responseDataModel.setErr_msg(ResultCodeEnum.PARAM_ERROR.getErr_msg());
            return responseDataModel;
        }
        //获取时间段内上课记录
        ReportsResult reportsResult = CommonData.getReports(starttime,
                endtime, courseid, null , null);
        Map<String,Course > courseMap = CommonData.getCourses(starttime);
        Map<String,Student > studentMap = CommonData.getStudentMap();
        Map<String,Teacher > teacherMap = CommonData.getTeachersMap();
        List<Student> students = new ArrayList<>();//存储该时间段内所有学生
        List<Teacher> teachers = new ArrayList<>();//存储该时间段内所有老师

        if(reportsResult.getResult_code() == 0){
            Map<String, Map<String,Reports>> reportsMap =
                    megreStudentDataByDate(reportsResult, studentMap, teacherMap, students, teachers);
            ClassPageResponse classPageResponse = new ClassPageResponse();
            //设置基本信息
            setBasicInfo(classPageResponse, students, teachers, courseMap.get(courseid),starttime, endtime);
            //获取出勤信息
            String date = DateUtil.isoStrToTargetStr(starttime, DateUtil.dateFormat2);
            Map<String,Reports> map = reportsMap.get(date);
            //获取昂立学生接口数据
            Map<String,StudentModel> angliStuMap = AngliCommonData.getStuMap(courseMap.get(courseid).getClass_id());

            if(null != map){
                setStatisticsInfo1(classPageResponse, date, map, studentMap, angliStuMap);
            }
            setChartInfo(classPageResponse, reportsMap, starttime, endtime, studentMap, students, angliStuMap);
            responseDataModel.setResponse(classPageResponse);
        } else {
            responseDataModel.setErr_code(reportsResult.getResult_code());
            responseDataModel.setErr_msg(reportsResult.getResult_msg());
        }
        return responseDataModel;
    }


    /**
     * 同一学生同一天同一课程数据合并
     * @param reportsResult
     * @return
     */
    public static Map<String, Map<String, Reports>>  megreStudentDataByDate(ReportsResult reportsResult,
                                                                            Map<String, Student> studentMap,
                                                                            Map<String, Teacher> teacherMap,
                                                                            List<Student> students,
                                                                            List<Teacher> teachers){
        Map<String, Reports> rMap;
        Reports re;
        Map<String, Map<String, Reports>> reportsMap = new HashMap<String, Map<String, Reports>>();
        List<Reports> reportsList = reportsResult.getReports();

        for (Reports report : reportsList){
            String reportDate = DateUtil.isoStrToTargetStr(
                    report.getStart_time(), DateUtil.dateFormat2);
            String sid = report.getStudent_id();
            String tid = report.getTeacher_id();
            //该段时间该课程所有学生集合
            if (!students.contains(studentMap.get(sid))) {
                students.add(studentMap.get(sid));
            }
            //该段时间该课程所有老师集合
            if (!teachers.contains(teacherMap.get(tid))) {
                teachers.add(teacherMap.get(tid));
            }
            rMap = reportsMap.get(reportDate);
            if(null != rMap){
                //同一学生同一天同一课程数据合并
                re = rMap.get(sid);
                if( null != re){
                    rMap.put(sid, re.megreReportsData(report));
                } else {
                    rMap.put(sid, report);
                }
            } else {
                rMap = new HashMap<>();
                rMap.put(sid, report);
                reportsMap.put(reportDate, rMap);
            }
        }
        return reportsMap;
    }

    /**
     * 获取基本信息
     * @param classPageResponse
     * @param students
     * @param teachers
     * @param course
     * @param starttime
     * @param endtime
     */
    public static void setBasicInfo(ClassPageResponse classPageResponse, List<Student>  students, List<Teacher> teachers,
                               Course course, String starttime, String endtime){
        List<String> studentNameList = new ArrayList<>(students.size());
        List<String> teacherNameList = new ArrayList<>(teachers.size());

        for (Student student : students){
            studentNameList.add(student.getName_ch());
        }
        for (Teacher teacher : teachers){
            teacherNameList.add(teacher.getName_ch());
        }
        classPageResponse.setStudents(studentNameList);
        classPageResponse.setTeachers(teacherNameList);
        classPageResponse.setDateFrom(DateUtil.isoStrToTargetStr(starttime, "yyyy/MM/dd"));
        classPageResponse.setDateTo(DateUtil.isoStrToTargetStr(endtime, "yyyy/MM/dd"));
        classPageResponse.setClassPic(course.getCover_picture());
        classPageResponse.setName(course.getName());
    }

    /**
     * 获取考勤信息
     * @param classPageResponse
     * @param date
     * @param reportsMap
     * @param studentMap
     */
    public static void setStatisticsInfo1(ClassPageResponse classPageResponse, String date,
                                          Map<String,Reports> reportsMap,Map<String,Student> studentMap,
                                          Map<String,StudentModel> studentModelMap){
        //昂立接口该班级实际学生
        Set<String> angliSet = studentModelMap.keySet();

        StatisticsInfo1 statisticsInfo1 = new StatisticsInfo1();
        statisticsInfo1.setDate(date);
        List<StudentInfo> studentInfos = new ArrayList<>();
        List<RegInfo> regInfo = new ArrayList<>();
        StudentInfo studentInfo;
        RegInfo reg;
        Student student;
        Reports reports;
        Integer yingdao = angliSet.size();
        Integer shidao = 0;
        Integer queqin = 0;
        Iterator<String> keys = reportsMap.keySet().iterator();
        while (keys.hasNext()){
            String key = keys.next();
            student = studentMap.get(key);
            reports = reportsMap.get(key);
            studentInfo = new StudentInfo(student.getName_ch(), student.getAvatar_url());
            studentInfos.add(studentInfo);
            int student_count = Integer.valueOf(reports.getStudent_count());
            if(shidao == 0){
                shidao = student_count;
            } else {
                if (shidao < student_count){
                    shidao = student_count;
                }
            }
            reg = new RegInfo(student.getName_ch(), DateUtil.isoStrToTargetStr(
                    reports.getStart_time(), "HH:mm"));
            regInfo.add(reg);
        }
        Info1Values values = new Info1Values();
        values.setChuqinlv(CommonUtils.getNum(((float)shidao/yingdao)*100.0f, "0.0") +"");
        values.setYingdao(yingdao);
        values.setShidao(shidao);
        values.setQueqin(yingdao - shidao);
        statisticsInfo1.setValues(values);
        statisticsInfo1.setRegInfo(regInfo);
        classPageResponse.setStatisticsInfo1(statisticsInfo1);
        classPageResponse.setStudentInfo(studentInfos);
    }



    public static void setChartInfo(ClassPageResponse classPageResponse,
                                    Map<String, Map<String,Reports>> reportsMap, String starttime,
                                    String endtime, Map<String,Student> studentMap,List<Student> students,
                                    Map<String,StudentModel> studentModelMap){
        //昂立接口该班级实际学生
        Set<String> angliSet = studentModelMap.keySet();

        List<ChartInfo> danrenpingjun = new ArrayList<>(); //单人所有平均值
        Map<String,Map<String,ChartInfo>> allInfo = new HashMap<>();

        Iterator<String> dateSet = reportsMap.keySet().iterator();
        Iterator<String> nameSet = null;

        //单人所有指标集合
        Map<String, Concentration> concentrationMap = new HashMap<>();
        Map<String, Emotion> emotionMap = new HashMap<>();
        Map<String, Vitality> vitalityMap = new HashMap<>();

        //所有人指标集合
        Concentration totalConcentration = new Concentration(0, 0, 0, 0);
        Emotion totalEmotion = new Emotion(0, 0 ,0 ,0);
        Vitality totalVitality = new Vitality(0,0,0,0,0);
        Integer yingdao = 0;
        Integer shidao = 0;

        Reports reports = null;
        Concentration concentration = null;
        Emotion emotion = null;
        Vitality vitality = null;
        ChartInfo chartInfo = null;

        //关注度指标最高
        Reports maxConcentration = null;
        //情绪指数最高
        Reports maxEmotion = null;
        //关注度指标最低
        Reports minConcentration = null;
        //情绪指数最低
        Reports minEmotion = null;

        while(dateSet.hasNext()){
            String dateKey = dateSet.next();
            Map<String,Reports> nameReMap = reportsMap.get(dateKey);
            Map<String,ChartInfo> dateChartMap = allInfo.get(dateKey);
            if(dateChartMap == null){
                dateChartMap = new HashMap<>();
                allInfo.put(dateKey, dateChartMap);
            }
            nameSet = nameReMap.keySet().iterator();
            int stucount = 0;
            while(nameSet.hasNext()){
                String nameKey = nameSet.next();
                reports = nameReMap.get(nameKey);
                concentration = reports.getConcentration();
                emotion = reports.getEmotion();
                vitality = reports.getVitality();
                //合并单人所有关注度数据供算单人平均数据
                if(concentrationMap.get(nameKey) == null){
                    concentrationMap.put(nameKey,concentration);
                } else {
                    concentrationMap.get(nameKey).megreConcentration(concentration);
                }
                //合并单人所有关情绪数据供算单人平均数据
                if(emotionMap.get(nameKey) == null){
                    emotionMap.put(nameKey,emotion);
                } else {
                    emotionMap.get(nameKey).megreEmotion(emotion);
                }
                //合并单人所有关活跃度数据供算单人平均数据
                if(vitalityMap.get(nameKey) == null){
                    vitalityMap.put(nameKey,vitality);
                } else {
                    vitalityMap.get(nameKey).megreVitality(vitality);
                }
                //计算单人单天数据供图表使用
                chartInfo = new ChartInfo();
                chartInfo.setStudentid(nameKey);
                chartInfo.setStudentName(studentMap.get(nameKey).getName_ch());
                chartInfo.setSdate(dateKey);
                chartInfo.setConcentration(concentration.getConcentrationData());
                chartInfo.setEmotion(emotion.getEmotionData());
                chartInfo.setVitality(vitality.getVitalityData());
                dateChartMap.put(nameKey, chartInfo);

                totalConcentration.megreConcentration(concentration);
                totalEmotion.megreEmotion(emotion);
                totalVitality.megreVitality(vitality);


                int c = Integer.valueOf(reports.getStudent_count());
                if(stucount == 0){
                    stucount = c;
                } else {
                    stucount = stucount > c? stucount:c ;
                }

                //获取最大关注度报告
                if(maxConcentration == null) {
                    maxConcentration = reports;
                } else {
                    if (maxConcentration.getConcentration().getConcentrationData()
                            < reports.getConcentration().getConcentrationData()) {
                        maxConcentration = reports;
                    }
                }

                //获取最小关注度报告
                if(minConcentration == null) {
                    minConcentration = reports;
                } else {
                    if(minConcentration.getConcentration().getConcentrationData()
                            > reports.getConcentration().getConcentrationData()){
                        minConcentration = reports;
                    }
                }

                //获取情绪指标最高值
                if(maxEmotion == null) {
                    maxEmotion = reports;
                } else {
                    if(maxEmotion.getEmotion().getEmotionData()
                            < reports.getEmotion().getEmotionData()){
                        maxEmotion = reports;
                    }
                }

                //获取情绪指标最低值
                if(minEmotion == null) {
                    minEmotion = reports;
                } else {
                    if(minEmotion.getEmotion().getEmotionData()
                            > reports.getEmotion().getEmotionData()){
                        minEmotion = reports;
                    }
                }
            }
            yingdao += angliSet.size();
            shidao += stucount;
        }

        //循环计算每个人的平均指标
        Iterator<String> iterator = concentrationMap.keySet().iterator();
        while(iterator.hasNext()){
            String key  = iterator.next();
            Student student = studentMap.get(key);
            ChartInfo chart = new ChartInfo();
            chart.setStudentid(key);
            chart.setStudentName(student.getName_ch());
            chart.setConcentration(concentrationMap.get(key).getConcentrationData());
            chart.setEmotion(emotionMap.get(key).getEmotionData());
            chart.setVitality(vitalityMap.get(key).getVitalityData());
            danrenpingjun.add(chart);
        }

        int n = DateUtil.getDiffDay(starttime,endtime);
        List<String> dates = new ArrayList<>();
        List<String> names = new ArrayList<>();

        for(Student student : students){
            names.add(student.getName_ch());
        }
        Map<String, DataModel1> scatterDataMap = new HashMap<>();
        Map<String, DataModel1> barData1Map = new HashMap<>();
        Map<String, DataModel1> barData2Map = new HashMap<>();
        Map<String, DataModel2> barData3Map = new HashMap<>();

        String d =
                DateUtil.isoStrToTargetStr(starttime, DateUtil.dateFormat2);
        //整合图表数据
        for( int i = 0 ; i< n ; i++){
            String startdate =
                    DateUtil.formatDate(d, DateUtil.dateFormat2,"MM月dd日");
            dates.add(startdate);
            Map<String, ChartInfo> sChartInfo = allInfo.get(d);

            if(sChartInfo == null ){
                d = DateUtil.ndaysDate(d,1,DateUtil.dateFormat2);
                continue;
            }
            for(Student student : students){
                ChartInfo chart = sChartInfo.get(student.get_id());
                if(chart == null ){
                    //scatterData 图
                    DataModel1 model1 = scatterDataMap.get(student.getName_ch());
                    if(model1 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(0f);
                        model1 = new DataModel1(student.getName_ch(), values);
                        scatterDataMap.put(student.getName_ch(), model1);
                    } else {
                        List<Float> values =  model1.getValues();
                        values.add(0f);
                    }
                    //barData1 图
                    DataModel1 model2 = barData1Map.get(student.getName_ch());
                    if(model2 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(0f);
                        model2 = new DataModel1(student.getName_ch(), values);
                        barData1Map.put(student.getName_ch(), model2);
                    }else {
                        List<Float> values =  model2.getValues();
                        values.add(0f);
                    }
                    //barData2 图
                    DataModel1 model3 = barData2Map.get(student.getName_ch());
                    if(model3 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(0f);
                        model3 = new DataModel1(student.getName_ch(), values);
                        barData2Map.put(student.getName_ch(), model3);
                    }else {
                        List<Float> values =  model3.getValues();
                        values.add(0f);
                    }
                    //barData3 图
                    DataModel2 model4 = barData3Map.get(startdate);
                    if(model4 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(0f);
                        model4 = new DataModel2(startdate, values);
                        barData3Map.put(startdate, model4);
                    }else {
                        List<Float> values =  model4.getValues();
                        values.add(0f);
                    }
                } else {
                    //scatterData 图
                    DataModel1 model1 = scatterDataMap.get(chart.getStudentName());
                    if(model1 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(chart.getConcentration());
                        model1 = new DataModel1(student.getName_ch(), values);
                        scatterDataMap.put(chart.getStudentName(), model1);
                    } else {
                        List<Float> values =  model1.getValues();
                        values.add(chart.getConcentration());
                    }
                    //barData1 图
                    DataModel1 model2 = barData1Map.get(chart.getStudentName());
                    if(model2 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(chart.getEmotion());
                        model2 = new DataModel1(student.getName_ch(), values);
                        barData1Map.put(chart.getStudentName(), model2);
                    }else {
                        List<Float> values =  model2.getValues();
                        values.add(chart.getEmotion());
                    }
                    //barData2 图
                    DataModel1 model3 = barData2Map.get(chart.getStudentName());
                    if(model3 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(chart.getVitality());
                        model3 = new DataModel1(student.getName_ch(), values);
                        barData2Map.put(chart.getStudentName(), model3);
                    }else {
                        List<Float> values =  model3.getValues();
                        values.add(chart.getVitality());
                    }
                    //barData3 图
                    DataModel2 model4 = barData3Map.get(startdate);
                    if(model4 == null){
                        List<Float> values = new ArrayList<>();
                        values.add(chart.getVitality());
                        model4 = new DataModel2(startdate, values);
                        barData3Map.put(startdate, model4);
                    }else {
                        List<Float> values =  model4.getValues();
                        values.add(chart.getVitality());
                    }
                }
            }
            d = DateUtil.ndaysDate(d, 1,DateUtil.dateFormat2);
        }
        //设置statisticsInfo2
        StatisticsInfo2 statisticsInfo2 = new StatisticsInfo2();
        statisticsInfo2.setPingjunzhi(totalConcentration.getConcentrationData() + "");
        danrenpingjun.sort(new SortComparator(1, "desc"));
        statisticsInfo2.setPingjunzuigao( danrenpingjun.get(0).getConcentration()
                + "(" + danrenpingjun.get(0).getStudentName() + ")") ;
        statisticsInfo2.setPingjunzuidi( danrenpingjun.get(danrenpingjun.size() -1 ).getConcentration()
                + "(" +  danrenpingjun.get(danrenpingjun.size() -1 ).getStudentName() + ")");
        statisticsInfo2.setZuidizhi( minConcentration.getConcentration().getConcentrationData()
                + "(" + studentMap.get(minConcentration.getStudent_id()).getName_ch() +")");
        statisticsInfo2.setZuigaozhi( maxConcentration.getConcentration().getConcentrationData()
                + "(" + studentMap.get(maxConcentration.getStudent_id()).getName_ch() +")");

        classPageResponse.setStatisticsInfo2(statisticsInfo2);

        ScatterData scatterData = new ScatterData();
        scatterData.setDates(dates);
        scatterData.setData(mapToList(scatterDataMap));
        classPageResponse.setScatterData(scatterData);

        //设置statisticsInfo3
        StatisticsInfo2 statisticsInfo3 = new StatisticsInfo2();
        statisticsInfo3.setPingjunzhi(totalEmotion.getEmotionData() + "");
        danrenpingjun.sort(new SortComparator(2, "desc"));
        statisticsInfo3.setPingjunzuigao( danrenpingjun.get(0).getEmotion()
                + "(" + danrenpingjun.get(0).getStudentName() + ")") ;
        statisticsInfo3.setPingjunzuidi( danrenpingjun.get(danrenpingjun.size() -1 ).getEmotion()
                + "(" +  danrenpingjun.get(danrenpingjun.size() -1 ).getStudentName() + ")");
        statisticsInfo3.setZuidizhi( minEmotion.getEmotion().getEmotionData()
                + "(" + studentMap.get(minEmotion.getStudent_id()).getName_ch() +")");
        statisticsInfo3.setZuigaozhi( maxEmotion.getEmotion().getEmotionData()
                + "(" + studentMap.get(maxEmotion.getStudent_id()).getName_ch() +")");
        classPageResponse.setStatisticsInfo3(statisticsInfo3);

        BarData barData1 = new BarData();
        barData1.setDates(dates);
        barData1.setData(mapToList(barData1Map));
        classPageResponse.setBarData1(barData1);

        BarData barData2 = new BarData();
        barData2.setDates(dates);
        barData2.setData(mapToList(barData2Map));
        classPageResponse.setBarData2(barData2);

        BarData3 barData3 = new BarData3();
        barData3.setNames(names);
        barData3.setData(mapToList(barData3Map));
        classPageResponse.setBarData3(barData3);

        List<Object[]> pieData = new ArrayList<>();
        Object[] chuqinlvArray = {"出勤率", CommonUtils.getNum(((float)shidao/yingdao)*100.0f, "0.0")};
        Object[] zhuanzhuzhishuArray = {"专注指数", totalConcentration.getConcentrationData()};
        Object[] qingxuzhishuArray = {"情绪指数", totalEmotion.getEmotionData()};
        Object[] canyuzhishi = {"参与指数", totalVitality.getVitalityData()};
        pieData.add(chuqinlvArray);
        pieData.add(zhuanzhuzhishuArray);
        pieData.add(qingxuzhishuArray);
        pieData.add(canyuzhishi);
        classPageResponse.setPieData(pieData);
    }


    public static List mapToList(Map map){
        List list = new ArrayList();
        Iterator<String> it = map.keySet().iterator();
        while(it.hasNext()){
            list.add(map.get(it.next()));
        }
        return  list;
    }


    public static void main(String[] args){
        //http://poc1.emotibot.com:3254/emotiedu/reports?starttime=2019-03-13T00:00:00.000Z&
        // endtime=2019-03-14T00:00:00.000Z&course_id=5c9345c935e1406cbc071939
        String s = JSONObject.toJSONString(ClassDataUtil.reponseData("2019-03-13T00:00:00.000Z","2019-03-25T00:00:00.000Z","5c9345c935e1406cbc071939",null));
        System.out.println(s);
    }
}
